<?php

namespace App\Services\Product;

use App\Exceptions\UserException;
use App\Facades\DeviceManager;
use App\Facades\UserManager;
use App\Facades\WeChatService as WeChat;
use App\Models\Role;
use App\Models\RoleUser;
use Cache;
use Carbon\Carbon;
use Cartalyst\Sentinel\Checkpoints\ThrottlingException;
use DB;
use Exception;
use Sentinel;

class UserService 
{
	/**
     * 创建或更新用户微信账号信息
     * @param  string  $code        授权 code
     */
    public function add($code)
    {
        $oAuthAccessToken = WeChat::oAuthAccessToken($code);

        if ($oAuthAccessToken){
            $userWxInfo = WeChat::getUserInfo($oAuthAccessToken);
            
            $user = Sentinel::findByCredentials(['username' => $userWxInfo['openid']]);
            DB::transaction(function() use ($user, $userWxInfo) {
	            if(is_null($user)){
	            	$user = Sentinel::registerAndActivate([
	                    'username' => $userWxInfo['openid'],
	                    'password' => 'password',
	                ]);
	            }
	            $this->addOrUpdateUserWxInfo($user, $userWxInfo);
            	session(['userId' => $user->id]);
	            Sentinel::login($user);
            });
        }
	}

	/**
	 * 添加或更新用户微信信息
	 * @param User $user       
	 * @param array $userWxInfo 
	 */
	public function addOrUpdateUserWxInfo($user, $userWxInfo)
	{
		try{
            $userInfo = UserManager::getUserInfoByOpenId($user->username);
			if(is_null($userInfo)){
				$data = [
					'user_id' => $user->id,
		            'open_id' => $userWxInfo['openid'],
		            'wx_nickname' => $userWxInfo['nickname'],
		            'wx_head_img_url' => $userWxInfo['headimgurl'],
		            'wx_sex' => $userWxInfo['sex'],
		            'wx_city' => $userWxInfo['city'],
		            'wx_province' => $userWxInfo['province'],
		            'wx_country' => $userWxInfo['country'],
					];
				UserManager::addUserInfo($data);
			}else{
				$data = [
		            'wx_nickname' => $userWxInfo['nickname'],
		            'wx_head_img_url' => $userWxInfo['headimgurl'],
		            'wx_sex' => $userWxInfo['sex'],
		            'wx_city' => $userWxInfo['city'],
		            'wx_province' => $userWxInfo['province'],
		            'wx_country' => $userWxInfo['country'],
					];
				UserManager::updateUserInfo($user->id, $data);
			}
		}catch(Exception $e){
			throw new UserException('wxInfo.add');
		}
	}

	/**
	 * 更新用户信息
	 * @param   $data 更新数据数组
	 * @return        
	 */
	public function updateUserInfo($data)
	{
		$user = UserManager::getUser();
		UserManager::updateUserInfo($user->id, $data);
	}

	/**
	 * 根据用户 id 更新用户信息
	 * @param  integer $userId 
	 * @param  array $data   
	 * @return          
	 */
	public function updateUserInfoByUserId($userId, $data)
	{
		$user = UserManager::getUserById($userId);
		UserManager::updateUserInfo($user->id, $data);
	}

	/**
	 * 添加售后服务消息
	 * @param  array $data 
	 */
	public function addAfterService($data)
	{
		$user = UserManager::getUser();
		$user = $user->load(['userInfo' => function($query){
			$query->select('user_id', 'current_device_id');
		}]);
		UserManager::addAfterService(array_merge([
										'user_id' => $user->id,
										'device_id' => $user->userInfo->current_device_id,
									], $data));
	}

	/**
	 * 根据用户获取用户信息
	 * @return 
	 */
	public function getUserInfoByUser()
	{
		return UserManager::getUser()->userInfo;
	}

	/**
	 * 登录
	 * @param   $credentials 
	 * @return               
	 */
	public function login($credentials)
	{
	    try{

	        $user = Sentinel::authenticate($credentials);
	        if(!$user){
	            throw new UserException('adminInfo.login');
	        }
	    }catch(ThrottlingException $e){
	        throw new UserException('loginThroot', "登录失败次数太多，请".$e->getDelay()."s后再尝试登录");
	    }
	}

	/**
	 * 添加管理员
	 * @param array $userData  
	 * @param array $adminData 
	 * @param integer $roleId    
	 */
	public function addAdmin($userData, $adminData, $roleId, $user = null)
	{
		if(is_null($user)){
			$user = UserManager::getUser();
		}
		try{
			DB::transaction(function() use ($userData, $adminData, $roleId) {
				$user = Sentinel::registerAndActivate($userData);
				if(!$user){
					throw new UserException('adminInfo.add');
				}
				UserManager::addAdminInfo(array_merge(['user_id' => $user->id], $adminData));
				$roleUser = RoleUser::create([
					'user_id' => $user->id,
					'role_id' => $roleId,
					]);
			});
		}catch(UserException $e){
			throw $e;
		}catch(Exception $e){
			throw new UserException('adminInfo.add');
		}
	}

	/**
	 * 更新密码
	 * @param  string $password    
	 * @param  string $newPassword 
	 * @return               
	 */
	public function updatePassword($password, $newPassword)
	{
		$user = UserManager::getUser();
        if(!$user)
        {
            return redirect('admin/login');
        }
        if(!Sentinel::validateCredentials($user, ['password' => $password]))
        {
            throw new UserException('adminInfo.password');
        }
        Sentinel::update($user, ['password' => $newPassword]);
	}

	/**
	 * 登出
	 * @return  
	 */
	public function logout()
	{
		$user = UserManager::getUser();
		Sentinel::logout($user, true);
	}

	/**
	 * 根据用户 id 更新管理员信息
	 * @param   $userId 	用户 id
	 * @param   $data   	用户信息更新数据数组
	 * @return          
	 */
	public function updateAdminInfo($userId, $data, $roleId = null)
	{
		DB::transaction(function() use ($userId, $data, $roleId) {
			$user = UserManager::getUserById($userId);
			$user->adminInfo->update($data);
			if(!is_null($roleId)){
				$roleUser = RoleUser::where('user_id', $userId)->first();
				$roleUser->update(['role_id' => $roleId]);
			}
		});
	}

	/**
	 * 根据用户 id 删除管理员
	 * @param   $userId 	用户 id
	 * @return          
	 */
	public function deleteAdmin($userId, $user = null)
	{
		if(is_null($user)){
			$user = UserManager::getUser();
		}
		if($user->id == $userId){
			throw new UserException('adminInfo.delete');
		}
		$user = UserManager::getUserById($userId);
		$user->delete();
	}

	/**
	 * 获取管理员并带有管理员信息
	 * @param  User $user 
	 * @return        
	 */
	public function getAllAdminWithInfo($user)
	{
		if($user->hasAccess(['superadmin'])){
			return UserManager::getAllAdminWithInfoAndRoleName();
		}else{
			return $this->loadAdminInfWIthRoleByUser($user);
		}
	}

	/**
	 * 根据 id 用户 管理员信息并带有用户名
	 * @param  integer  $userId 
	 * @return          
	 */
	public function findAdminInfoByIdWithUsername($userId)
	{
		$user = UserManager::getUserById($userId);
		return $this->loadAdminInfWIthRoleByUser($user);
	}
	
	/**
	 * 根据用户获取管理员信息并带有角色
	 * @param  User  $user 
	 * @return        
	 */
	public function loadAdminInfWIthRoleByUser($user){
		return $user->load(['adminInfo' => function($query){
			$query->select('user_id', 'name', 'phone');
		}, 'roles' => function($query){
				$query->select('id', 'name');
			}]);
	}

	/**
	 * 获取用户列表并带有用户信息
	 * @param  string $condition 
	 * @return             
	 */
	public function findCustomerListWithUserInfo($condition)
	{
		$userInfoBuilder = UserManager::findUserInfoBuilder($condition, ['user_id', 'name', 'sex', 'phone', 'installation_address', 'current_device_id']);
		$installInfos = DeviceManager::getInstallInfoListBuilderOrderByCreatedAt()->where('customer_name', 'like', '%'.$condition.'%')->select('id', 'dealer', 'device_code')->get();
		// $installInfos = DeviceManager::getInstallInfoListBuilderOrderByCreatedAt()->where('dealer', 'like', '%'.$condition.'%')->select('id', 'dealer', 'device_code')->get();
		$devices = DeviceManager::getDeviceBuilderOrderByCreatedAt()->whereIn('code', $installInfos->pluck('device_code'))->get();
		$query = $userInfoBuilder->whereNotNull('current_device_id')->orWhereIn('current_device_id', $devices->pluck('id'));
		return $query->with(['device' => function($query){
			$query->with(['installInfo' => function($query){
				$query->select('device_code', 'dealer', 'customer_name');
			}])->select('id', 'code');
		}])->paginate(15);
	}

	/**
	 * 获取售后服务列表
	 * @param  string  $condition 
	 * @return              
	 */
	public function findAfterServiceList($condition)
	{
		$devices = DeviceManager::findDeviceByDeviceCode($condition);
		$deviceIds = DeviceManager::findDevicesByCustomerName($condition);
		$AfterServiceBuilder = UserManager::getAfterServiceListBuilderByDeviceIds($condition, array_merge($devices->pluck('id')->toArray(), $deviceIds->pluck('id')->toArray()));
		return $AfterServiceBuilder->with(['device' => function($query){
			$query->with(['installInfo' => function($query){
				$query->select('device_code', 'customer_name');
			}])->select('id', 'code');
		}])->paginate(15);
	}

	/**
	 * 获取全部角色信息
	 * @return  
	 */
	public function roles()
	{
		$roles = Role::select('id', 'slug')->get();
		if(count($roles)){
			return $roles;
		}
		throw new UserException('role.notFound');
	}

	/**
	 * 根据 id 获取用户信息
	 * @param  integer $userId 
	 * @return          
	 */
	public function getUserInfoById($userId)
	{
		$userInfo = UserManager::getUserInfoByUserId($userId, ['name', 'sex', 'phone', 'installation_address']);
		if(is_null($userInfo)){
			throw new UserException('info.notFound');
		}
		return $userInfo;
	}

	/**
	 * 更新售后服务信息
	 * @param  integer $id    
	 * @param  integer $status
	 * @return  
	 */
	public function updateAfterServiceById($id, $status)
	{
		$afterService = UserManager::getAfterServiceListById($id);
		$afterService->update($status);
		return $afterService;
	}

	/**
	 * 根据状态对售后服务计数
	 * @param  integer  $status 
	 * @return          
	 */
	public function countAfterServiceListByStatus($status)
	{
		return UserManager::countAfterServiceListByStatus($status);
	}

	/**
	 * 是否为有权限
	 * @param  array  $permission 
	 * @return boolean             
	 */
	public function hasPermission($permission)
	{
		$user = UserManager::getUser();
		if(!$user->hasAnyAccess($permission)){
			throw new UserException('auth');
		}
		return $user;
	}




}